#include "pagerank.h"

#include <stdio.h>
#include <QDebug>
#include <numeric>

PageRank::PageRank(QObject *parent) : QObject(parent)
{
    VexNum = 0;
    totalVex = 0;
    AdjMatrix.clear();
}

void PageRank::SetVex(int n,int del)
{
    VexNum = n;
    int OldSize = AdjMatrix.size();
    if(n>OldSize){
        prValue.resize(n);
        AdjMatrix.resize(n);//qDebug("adj.size = %d",AdjMatrix.size());
        for(int i = 0;i<n;i++){
            AdjMatrix[i].resize(n);//qDebug("adj[%d].size = %d",i,AdjMatrix[i].size());
        }
        for(int i = 0;i<n;i++){
            if(i<OldSize)
                for(int j = OldSize;j<n;j++) AdjMatrix[i][j] = 0;
            else
                for(int j = 0;j<n;j++) AdjMatrix[i][j] = 0;
        }
    }
    else if(del>-1){
        prValue.removeAt(del);
        AdjMatrix.removeAt(del);
        for(int i = 0;i<AdjMatrix.size();i++) AdjMatrix[i].removeAt(del);
    }
    else if(n == 0){
        prValue.resize(n);
        AdjMatrix.resize(n);//qDebug("adj.size = %d",AdjMatrix.size());
        for(int i = 0;i<n;i++){
            AdjMatrix[i].resize(n);//qDebug("adj[%d].size = %d",i,AdjMatrix[i].size());
        }
    }

}

void PageRank::SwicthAt(int i,int j)
{
    AdjMatrix[i][j] = (AdjMatrix[i][j]+1)%2;


}

void PageRank::Rank()
{
    QVector<double> pr(VexNum,1.0/VexNum); //存储pr值
    QVector<double> next_pr(VexNum);  //存储后一次迭代结果
    QVector<QVector<double>> Pmatrix(VexNum,QVector<double>(VexNum+1,0)); //幂次迭代矩阵
    for(int i = 0;i<VexNum;i++){
        for(int j = 0;j<VexNum;j++)
            Pmatrix[i][VexNum] += AdjMatrix[i][j];
    }
    for(int i = 0;i<VexNum;i++){
        for(int j = 0;j<VexNum;j++){
            Pmatrix[i][j] = 0.15/VexNum;
            if(AdjMatrix[i][j]) Pmatrix[i][j] += 0.85/Pmatrix[i][VexNum];

        }
    }
    for(int j = 0;j<VexNum;j++){
        double k = 0;
        for(int i = 0;i<VexNum;i++)
            k += Pmatrix[i][j]*pr[i];
        next_pr[j] = k;
    }
    int i = 0;
    while(pr!=next_pr){ //迭代至pr收敛
        pr = next_pr;
        i++;
        if(i>2000){  //迭代次数上限设为2000（精度足够）
            prValue = pr;
            return ;
        }
        for(int j = 0;j<VexNum;j++){
            double k = 0;
            for(int i = 0;i<VexNum;i++)
                k += Pmatrix[i][j]*pr[i];
            next_pr[j] = k;
        }

    }
    prValue = pr;
    return ;
}
